package com.jl.security.mac;

import java.security.GeneralSecurityException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class ALG_DES_MAC8_ISO9797_1_M2_ALG3 implements IMac{

	private byte[] key1 = new byte[8];
	private byte[] key2 = new byte[8];
	private byte[] res = new byte[4];
	private byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
	
	private byte[] data;

	private void generateMac() throws GeneralSecurityException {
		SecretKey skey1 = new SecretKeySpec(this.key1, "DES");
		SecretKey skey2 = new SecretKeySpec(this.key2, "DES");
		Cipher cipher = Cipher.getInstance("DES/CBC/Nopadding");
		IvParameterSpec ivp = new IvParameterSpec(iv);
		cipher.init(Cipher.ENCRYPT_MODE, skey1, ivp);
		byte[] data1 = cipher.doFinal(data);
		byte[] data2 = new byte[8];
		System.arraycopy(data1, data1.length - 8, data2, 0, 8);
		Cipher cipher2 = Cipher.getInstance("DES/ECB/Nopadding");
		cipher2.init(Cipher.DECRYPT_MODE, skey2);
		byte[] data3 = cipher2.doFinal(data2);
		Cipher cipher3 = Cipher.getInstance("DES/ECB/Nopadding");
		cipher3.init(Cipher.ENCRYPT_MODE, skey1);
		byte[] mac = cipher3.doFinal(data3);
		res = mac;
	}

	@Override
	public byte[] doFinal(byte[] data) throws GeneralSecurityException {
        int len = (data.length / 8 + 1) * 8;
        byte[] dataTemp = new byte[len];
        System.arraycopy(data, 0, dataTemp, 0, data.length);
        byte[] padding = new byte[]{(byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        System.arraycopy(padding, 0, dataTemp, data.length, dataTemp.length - data.length);
        this.data = dataTemp;
        generateMac();
        return res;  
    }

	@Override
	public void initKey(byte[] key) {
		System.arraycopy(key, 0, this.key1, 0, 8);
		System.arraycopy(key, 8, this.key2, 0, 8);
	}

	@Override
	public void initIV(byte[] IV) {
		System.arraycopy(IV, 0, this.iv, 0, 8);
	}
}
